home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Cross Platform / QuickTime 4.1.2 Windows SDK / CIncludes / Math64.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-12  |  12.4 KB  |  408 lines  |  [TEXT/R*ch]

  1. /*
  2.      File:        Math64.h
  3.  
  4.      Contains:    64-bit integer math Interfaces.
  5.  
  6.      Version:    Technology:    System 7.5
  7.                  Release:    QuickTime 4.1
  8.  
  9.      Copyright:    (c) 1994-1999 by Apple Computer, Inc., all rights reserved
  10.  
  11.      Bugs?:        For bug reports, consult the following page on
  12.                  the World Wide Web:
  13.  
  14.                      http://developer.apple.com/bugreporter/
  15.  
  16. */
  17. #ifndef __MATH64__
  18. #define __MATH64__
  19.  
  20. #ifndef __CONDITIONALMACROS__
  21.     #include <ConditionalMacros.h>
  22. #endif
  23.  
  24. #ifndef __MACTYPES__
  25.     #include <MacTypes.h>
  26. #endif
  27.  
  28.  
  29.  
  30.  
  31. #if PRAGMA_ONCE
  32. #pragma once
  33. #endif
  34.  
  35. #ifdef __cplusplus
  36. extern "C" {
  37. #endif
  38.  
  39. #if PRAGMA_IMPORT
  40. #pragma import on
  41. #endif
  42.  
  43. #if PRAGMA_STRUCT_ALIGN
  44.     #pragma options align=mac68k
  45. #elif PRAGMA_STRUCT_PACKPUSH
  46.     #pragma pack(push, 2)
  47. #elif PRAGMA_STRUCT_PACK
  48.     #pragma pack(2)
  49. #endif
  50.  
  51.  
  52. /*--------------------------------------------------------------------------------
  53.                 These routines are intended to provide C software support for
  54.                 64 bit integer types.  Their behavior should mimic anticipated
  55.                 64 bit hardware. This implementation should replace use of the
  56.                 "wide" type found in PowerPC.
  57.  
  58.     The following routines are available for performing math on 64-bit integers:
  59.     
  60.     S64Max
  61.                 Returns the largest representable SInt64.
  62.     S64Min
  63.                 Returns the smallest (i.e. most negative) SInt64.  Note: the negative
  64.                 (absolute value) of this number is not representable in an SInt64.
  65.                 That means that S64Negate(S64Min) is not representable (in fact,
  66.                 it returns S64Min).
  67.     S64Add
  68.                 Adds two integers, producing an integer result.  If an overflow
  69.                 occurs the result is congruent mod (2^64) as if the operands and
  70.                 result were unsigned.  No overflow is signaled.
  71.     
  72.     S64Subtract
  73.                 Subtracts two integers, producing an integer result.  If an overflow
  74.                 occurs the result is congruent mod (2^64) as if the operands and
  75.                 result were unsigned.  No overflow is signaled.
  76.  
  77.     S64Negate
  78.                 Returns the additive inverse of a signed number (i.e. it returns
  79.                 0 - the number).  S64Negate (S64Min) is not representable (in fact,
  80.                 it returns S64Min).
  81.     
  82.     S64Absolute
  83.                 Returns the absolute value of the number (i.e. the number if
  84.                 it is positive, or 0 - the number if it is negative).
  85.                 See S64Negate above.
  86.                 
  87.     S64Multiply
  88.                 Multiplies two signed numbers, producing a signed result.  Overflow
  89.                 is ignored and the low-order part of the product is returned.  The
  90.                 sign of the result is not guaranteed to be correct if the magnitude
  91.                 of the product is not representable.
  92.                 
  93.     S64Div
  94.                 Divides dividend by divisor, returning the quotient.
  95.                 
  96.     S64Mod
  97.                 Returns the remainder of divide of dividend by divisor.  The sign of
  98.                 the remainder is the same as the sign of the dividend (i.e., it takes
  99.                 the absolute values of the operands, does the division, then fixes
  100.                 the sign of the quotient and remainder).
  101.  
  102.     S64Divide
  103.                 Divides dividend by divisor, returning the quotient.  The remainder
  104.                 is returned in *remainder if remainder (the pointer) is non-NULL.
  105.                 The sign of the remainder is the same as the sign of the dividend
  106.                 (i.e. it takes the absolute values of the operands, does the division,
  107.                 then fixes the sign of the quotient and remainder).  If the divisor
  108.                 is zero, then S64Max() will be returned (or S64Min() if the dividend
  109.                 is negative), and the remainder will be the dividend; no error is
  110.                 reported.
  111.     
  112.     S64Set
  113.                 Given an SInt32, returns an SInt64 with the same value.  Use this
  114.                 routine instead of coding 64-bit constants (at least when the
  115.                 constant will fit in an SInt32).
  116.     
  117.     S64SetU
  118.                 Given a UInt32, returns a SInt64 with the same value.
  119.                 
  120.     S64Set
  121.                 Given an SInt64, returns an SInt32 by discarding the high-order
  122.                 32 bits.
  123.     
  124.     S64Compare
  125.                 Given two signed numbers, left and right, returns an
  126.                 SInt32 that compares with zero the same way left compares with
  127.                 right.  If you wanted to perform a comparison on 64-bit integers
  128.                 of the form:
  129.                         operand_1 <operation> operand_2
  130.                 then you could use an expression of the form:
  131.                         xxxS64Compare(operand_1,operand_2) <operation> 0
  132.                 to test for the same condition.
  133.                 
  134.                 CAUTION: DO NOT depend on the exact value returned by this routine.
  135.                 Only the sign (i.e. positive, zero, or negative) of the result is
  136.                 guaranteed.
  137.  
  138.     S64And, S64Or, S64Eor and S64Not
  139.     
  140.                 Return Boolean (1 or 0) depending on the outcome of the logical
  141.                 operation.
  142.  
  143.     S64BitwiseAnd, S64BitwiseOr, S64BitwiseEor and S64BitwiseNot
  144.     
  145.                 Return the Bitwise result.
  146.                 
  147.     S64ShiftRight and S64ShiftLeft
  148.     
  149.                 The lower 7 bits of the shift argument determines the amount of 
  150.                 shifting.  S64ShiftRight is an arithmetic shift while U64ShiftRight
  151.                 is a logical shift.
  152.  
  153.     SInt64ToLongDouble
  154.                 
  155.                 Converts SInt64 to long double.  Note all SInt64s fit exactly into 
  156.                 long doubles, thus, the binary -> decimal conversion routines
  157.                 in fp.h can be used to achieve SInt64 -> long double -> decimal
  158.                 conversions.
  159.                 
  160.     LongDoubleToSInt64
  161.     
  162.                 Converts a long double to a SInt64.  Any decimal string that fits
  163.                 into a SInt64 can be converted exactly into a long double, using the
  164.                 conversion routines found in fp.h.  Then this routine can be used
  165.                 to complete the conversion to SInt64.
  166.                 
  167.     SInt64ToWide
  168.     
  169.                 Converts a SInt64 to a wide struct.  If SInt64 is implemented
  170.                 as a typedef of wide, the marco does nothing. If SInt64 is 
  171.                 implememnted as a long long, it casts the long long into a 
  172.                 wide struct.
  173.     
  174.     WideToSInt64
  175.     
  176.                 Converts a wide struct into a SInt64.  If SInt64 is implemented
  177.                 as a typedef of wide, the marco does nothing. If SInt64 is 
  178.                 implememnted as a long long, it reads the struct into a long long.
  179.     
  180.     
  181.     The corresponding UInt64 routines are also included.
  182.     
  183. --------------------------------------------------------------------------------*/
  184.  
  185. #if TYPE_LONGLONG
  186.  
  187. #ifdef __MRC__
  188.     #define S64Max() 9223372036854775807LL
  189. #else
  190.     #define S64Max() 9223372036854775807
  191. #endif
  192. #define S64Min() (-S64Max() - 1)
  193. #define S64Add(x, y) ((SInt64) (x) + (SInt64) (y))
  194. #define S64Subtract(x, y) ((SInt64) (x) - (SInt64) (y))
  195. #define S64Negate(x) (-(SInt64) (x))
  196. #define S64Absolute(x) absll((SInt64) (x))
  197. #define S64Multiply(x, y) ((SInt64) (x) * (SInt64) (y))
  198. #define S64Div(x, y) ((SInt64) (x) / (SInt64) (y))
  199. #define S64Mod(x, y) ((SInt64) (x) % (SInt64) (y))
  200. #define S64Set(x) ((SInt64) (x))
  201. #define S64SetU(x) ((SInt64) (x))
  202. #define S32Set(x) ((SInt32) (x))
  203.  
  204. #define S64And(x, y) ((Boolean)((SInt64) (x) && (SInt64) (y)))
  205. #define S64Or(x, y) ((Boolean)((SInt64) (x) || (SInt64) (y)))
  206. #define S64Eor(x, y) ((Boolean)((SInt64) (x) ^ (SInt64) (y)))
  207. #define S64Not(x) ((Boolean)(!(SInt64) (x)))
  208. #define S64BitwiseAnd(x, y) ((SInt64) (x) & (SInt64) (y))
  209. #define S64BitwiseOr(x, y) ((SInt64) (x) | (SInt64) (y))
  210. #define S64BitwiseEor(x, y) (((SInt64) (x) & (~(SInt64) (y))) | ((~(SInt64) (x)) & (SInt64) (y)))
  211. #define S64BitwiseNot(x) (~(SInt64) (x))
  212. #define S64ShiftRight(x, y) ((SInt64) (x) >> (UInt32) (y))
  213. #define S64ShiftLeft(x, y) ((SInt64) (x) << (UInt32) (y))
  214. #define SInt64ToLongDouble(x) ((long double)(x))
  215. #define LongDoubleToSInt64(x) ((SInt64)(x))
  216.  
  217.  
  218. #ifdef __MRC__
  219.     #define U64Max() 0xffffffffffffffffULL
  220. #else
  221.     #define U64Max() 0xffffffffffffffff
  222. #endif
  223. #define U64Add(x, y) ((UInt64) (x) + (UInt64) (y))
  224. #define U64Subtract(x, y) ((UInt64) (x) - (UInt64) (y))
  225. #define U64Multiply(x, y) ((UInt64) (x) * (UInt64) (y))
  226. #define U64Div(x, y) ((UInt64) (x) / (UInt64) (y))
  227. #define U64Mod(x, y) ((UInt64) (x) % (UInt64) (y))
  228. #define U64Set(x) ((UInt64) (x))
  229. #define U64SetU(x) ((UInt64) (x))
  230. #define U32SetU(x) ((UInt32) (x))
  231.  
  232. #define U64And(x, y) ((Boolean)((UInt64) (x) && (UInt64) (y)))
  233. #define U64Or(x, y) ((Boolean)((UInt64) (x) || (UInt64) (y)))
  234. #define U64Eor(x, y) ((Boolean)((UInt64) (x) ^ (UInt64) (y)))
  235. #define U64Not(x) ((Boolean)(!(UInt64) (x)))
  236. #define U64BitwiseAnd(x, y) ((UInt64) (x) & (UInt64) (y))
  237. #define U64BitwiseOr(x, y) ((UInt64) (x) | (UInt64) (y))
  238. #define U64BitwiseEor(x, y) (((UInt64) (x) & (~(UInt64) (y))) | ((~(UInt64) (x)) & (UInt64) (y)))
  239. #define U64BitwiseNot(x) (~(UInt64) (x))
  240. #define U64ShiftRight(x, y) ((UInt64) (x) >> (UInt32) (y))
  241. #define U64ShiftLeft(x, y) ((UInt64) (x) << (UInt32) (y))
  242. #define UInt64ToLongDouble(x) ((long double)(x))
  243. #define LongDoubleToUInt64(x) ((UInt64)(x))
  244. #define UInt64ToSInt64(x) ((SInt64)(x))
  245. #define SInt64ToUInt64(x) ((UInt64)(x))
  246.  
  247. #else
  248. EXTERN_API_C( SInt64 ) S64Max(void );
  249.  
  250. EXTERN_API_C( SInt64 ) S64Min(void );
  251.  
  252. EXTERN_API_C( SInt64 ) S64Add(SInt64 x, SInt64 y);
  253.  
  254. EXTERN_API_C( SInt64 ) S64Subtract(SInt64 left, SInt64 right);
  255.  
  256. EXTERN_API_C( SInt64 ) S64Negate(SInt64 value);
  257.  
  258. EXTERN_API_C( SInt64 ) S64Absolute(SInt64 value);
  259.  
  260. EXTERN_API_C( SInt64 ) S64Multiply(SInt64 xparam, SInt64 yparam);
  261.  
  262. #define S64Div(dividend, divisor) S64Divide(dividend, divisor, NULL)
  263.  
  264. EXTERN_API_C( SInt64 ) S64Mod(SInt64 dividend, SInt64 divisor);
  265.  
  266. EXTERN_API_C( SInt64 ) S64Divide(SInt64 dividend, SInt64 divisor, SInt64 *remainder);
  267.  
  268. EXTERN_API_C( SInt64 ) S64Set(SInt32 value);
  269.  
  270. EXTERN_API_C( SInt64 ) S64SetU(UInt32 value);
  271.  
  272. EXTERN_API_C( SInt32 ) S32Set(SInt64 value);
  273.  
  274. EXTERN_API_C( Boolean ) S64And(SInt64 left, SInt64 right);
  275.  
  276. EXTERN_API_C( Boolean ) S64Or(SInt64 left, SInt64 right);
  277.  
  278. EXTERN_API_C( Boolean ) S64Eor(SInt64 left, SInt64 right);
  279.  
  280. EXTERN_API_C( Boolean ) S64Not(SInt64 value);
  281.  
  282. EXTERN_API_C( SInt64 ) S64BitwiseAnd(SInt64 left, SInt64 right);
  283.  
  284. EXTERN_API_C( SInt64 ) S64BitwiseOr(SInt64 left, SInt64 right);
  285.  
  286. EXTERN_API_C( SInt64 ) S64BitwiseEor(SInt64 left, SInt64 right);
  287.  
  288. EXTERN_API_C( SInt64 ) S64BitwiseNot(SInt64 value);
  289.  
  290. EXTERN_API_C( SInt64 ) S64ShiftRight(SInt64 value, UInt32 shift);
  291.  
  292. EXTERN_API_C( SInt64 ) S64ShiftLeft(SInt64 value, UInt32 shift);
  293.  
  294. /*
  295.     "long double" means 128 bit type on PowerPC and 80-bit type on 68K
  296. */
  297. EXTERN_API_C( long double ) SInt64ToLongDouble(SInt64 value);
  298.  
  299. EXTERN_API_C( SInt64 ) LongDoubleToSInt64(long double value);
  300.  
  301. EXTERN_API_C( UInt64 ) U64Max(void );
  302.  
  303. EXTERN_API_C( UInt64 ) U64Add(UInt64 x, UInt64 y);
  304.  
  305. EXTERN_API_C( UInt64 ) U64Subtract(UInt64 left, UInt64 right);
  306.  
  307. EXTERN_API_C( UInt64 ) U64Multiply(UInt64 xparam, UInt64 yparam);
  308.  
  309. #define U64Div(dividend, divisor) U64Divide(dividend, divisor, NULL)
  310.  
  311. EXTERN_API_C( UInt64 ) U64Mod(UInt64 dividend, UInt64 divisor);
  312.  
  313. EXTERN_API_C( UInt64 ) U64Divide(UInt64 dividend, UInt64 divisor, UInt64 *remainder);
  314.  
  315. EXTERN_API_C( UInt64 ) U64Set(SInt32 value);
  316.  
  317. EXTERN_API_C( UInt64 ) U64SetU(UInt32 value);
  318.  
  319. EXTERN_API_C( UInt32 ) U32SetU(UInt64 value);
  320.  
  321. EXTERN_API_C( Boolean ) U64And(UInt64 left, UInt64 right);
  322.  
  323. EXTERN_API_C( Boolean ) U64Or(UInt64 left, UInt64 right);
  324.  
  325. EXTERN_API_C( Boolean ) U64Eor(UInt64 left, UInt64 right);
  326.  
  327. EXTERN_API_C( Boolean ) U64Not(UInt64 value);
  328.  
  329. EXTERN_API_C( UInt64 ) U64BitwiseAnd(UInt64 left, UInt64 right);
  330.  
  331. EXTERN_API_C( UInt64 ) U64BitwiseOr(UInt64 left, UInt64 right);
  332.  
  333. EXTERN_API_C( UInt64 ) U64BitwiseEor(UInt64 left, UInt64 right);
  334.  
  335. EXTERN_API_C( UInt64 ) U64BitwiseNot(UInt64 value);
  336.  
  337. EXTERN_API_C( UInt64 ) U64ShiftRight(UInt64 value, UInt32 shift);
  338.  
  339. EXTERN_API_C( UInt64 ) U64ShiftLeft(UInt64 value, UInt32 shift);
  340.  
  341. /*
  342.     "long double" means 128 bit type on PowerPC and 80-bit type on 68K
  343. */
  344. EXTERN_API_C( long double ) UInt64ToLongDouble(UInt64 value);
  345.  
  346. EXTERN_API_C( UInt64 ) LongDoubleToUInt64(long double value);
  347.  
  348. EXTERN_API_C( SInt64 ) UInt64ToSInt64(UInt64 value);
  349.  
  350. EXTERN_API_C( UInt64 ) SInt64ToUInt64(SInt64 value);
  351.  
  352. #endif  /* TYPE_LONGLONG */
  353.  
  354. EXTERN_API_C( SInt32 ) S64Compare(SInt64 left, SInt64 right);
  355.  
  356. EXTERN_API_C( SInt32 ) U64Compare(UInt64 left, UInt64 right);
  357.  
  358.  
  359. // sam says you want these to be dispatched routines
  360. #if TARGET_OS_WIN32 && TYPE_LONGLONG
  361. #define S64Compare(left,right) ((int)(left - right))
  362. #define U64Compare(left,right) ((int)(left - right))
  363. #endif
  364.  
  365.  
  366. /* 
  367.     Functions to convert between [Unsigned]Wide and [S|U]Int64 types.
  368.     
  369.     These functions are necessary if source code which uses both
  370.     wide and SInt64 is to compile under a compiler that supports
  371.     long long.
  372. */
  373. #if TYPE_LONGLONG 
  374.     #define SInt64ToWide(x)         (*((wide*)(&x)))
  375.     #define WideToSInt64(x)         (*((SInt64*)(&x)))
  376.     #define UInt64ToUnsignedWide(x) (*((UnsignedWide*)(&x)))
  377.     #define UnsignedWideToUInt64(x) (*((UInt64*)(&x)))
  378. #else
  379.     #define SInt64ToWide(x)         (x)
  380.     #define WideToSInt64(x)         (x)
  381.     #define UInt64ToUnsignedWide(x) (x)
  382.     #define UnsignedWideToUInt64(x) (x)
  383. #endif
  384.  
  385.  
  386.  
  387.  
  388. #if PRAGMA_STRUCT_ALIGN
  389.     #pragma options align=reset
  390. #elif PRAGMA_STRUCT_PACKPUSH
  391.     #pragma pack(pop)
  392. #elif PRAGMA_STRUCT_PACK
  393.     #pragma pack()
  394. #endif
  395.  
  396. #ifdef PRAGMA_IMPORT_OFF
  397. #pragma import off
  398. #elif PRAGMA_IMPORT
  399. #pragma import reset
  400. #endif
  401.  
  402. #ifdef __cplusplus
  403. }
  404. #endif
  405.  
  406. #endif /* __MATH64__ */
  407.  
  408.